package customerEnter.Frame.scanning.scanningServer;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.dom4j.DocumentException;

import customerEnter.Frame.Annotation.FrameAttributes;
import customerEnter.Frame.Annotation.FrameExtraAttributes;
import customerEnter.Frame.DaoDataTransmission.ConfigXml;
import customerEnter.Frame.DaoDataTransmission.ConfigXmlBean;
import customerEnter.Frame.DaoDataTransmission.WebAppsInfo;
import customerEnter.Frame.Utils.FileUtils;
import customerEnter.Frame.Utils.Log4j;
import customerEnter.Frame.bean.FrameBeansModels;
import customerEnter.Frame.scanning.ScanningAnalysis;
import customerEnter.Frame.scanning.ScanningExtendedConfig;
import customerEnter.tool.WhetherToEmpty;

/**
 * 掃描包的類
 * 
 * 类名称：ProjectScanningServer 类描述： 创建人：dy 创建时间：2017-4-5 下午5:52:42
 * 
 */
public class ProjectScanningModelServer implements ScanningExtendedConfig {

	public Map<String, Class<?>> scanningPackage(ScanningAnalysis analysis) {
		Map<String, Class<?>> map = new HashMap<String, Class<?>>();
		ConfigXml configXml = null;
		try {
			configXml = analysis.scanningConfigPackage(WebAppsInfo.webUrl + "\\WEB-INF\\classes\\frame.xml");
		} catch (DocumentException e) {
			Log4j.Log4jOutInfo(e.getMessage());
		}
		if (WhetherToEmpty.ObjectWhetherToEmpty(configXml)) {
			return new HashMap<String, Class<?>>();
		}
		/**
		 * 循環第一層標籤
		 */
		for (ConfigXmlBean configXmlBean : configXml.getConfigXmlBeans()) {
			/**
			 * 循環第二層標籤
			 */
			for (ConfigXmlBean configXmlBean2 : configXmlBean.getLabelBean()) {
				try {

					String path = WebAppsInfo.webUrl + "/WEB-INF/classes/"
							+ configXmlBean2.getValue().replace(".", "/");
					System.out.println("掃描路徑：" + path);
					/**
					 * 循環掃描包下面的文件
					 */
					FileUtils.readfile(path, map, "");
				} catch (Exception e) {
					Log4j.Log4jOutInfo(e.getMessage());
				}
			}
		}
		return map;
	}

	public Map<String, Field[]> scanningClass(Map<String, Class<?>> map) {
		return null;
	}

	public Map<String, FrameBeansModels> scanningClassModels(Map<String, Class<?>> map) {
		Map<String, FrameBeansModels> frameBeansModels = new HashMap<String, FrameBeansModels>();
		// 循環所有的bean
		for (Entry<String, Class<?>> entry : map.entrySet()) {
			FrameBeansModels frameBeansModel = new FrameBeansModels();
			// 判斷是不是有註解的過FrameAttributes 的類型
			getFrameBeansModels(entry.getValue().getDeclaredFields(), frameBeansModel);
			frameBeansModels.put(entry.getValue().getName(), frameBeansModel);
		}
		return frameBeansModels;
	}

	/**
	 * 判斷有沒有用類做屬性
	 */
	public boolean IfFrameAttributes(Field[] fields) {
		boolean bool = false;
		for (Field field : fields) {
			field.setAccessible(true);
			if (!WhetherToEmpty.ObjectWhetherToEmpty(field.getAnnotation(FrameAttributes.class))) {
				bool = true;
				break;
			}
		}
		return bool;
	}

	public void getFrameBeansModels(Field[] fieldsOld, FrameBeansModels frameBeansModel) {
		Field[] fields = getIsAttributesFields(fieldsOld);// 沒有註解的 屬性
		// 如果是attributes 屬性
		if (IfFrameAttributes(fieldsOld)) {
			// 存儲所有沒有註解的屬性
			frameBeansModel.setFields(fields);
			// 獲取到所有的註解類型並且放入map
			setAttributesFramsModel(fieldsOld, frameBeansModel);
		} else {
			frameBeansModel.setFields(fields);
		}
	}

	// 獲取所有需要的屬性 （不需要serialVersionUID 和 FrameExtraAttributes 的屬性）
	public Field[] getIsAttributesFields(Field[] fields) {
		Field[] fields2 = new Field[fields.length];
		int i = 0;
		for (Field field : fields) {
			if (!WhetherToEmpty.ObjectWhetherToEmpty(field.getAnnotation(FrameExtraAttributes.class))
					|| "serialVersionUID".equals(field.getName())
					|| !WhetherToEmpty.ObjectWhetherToEmpty(field.getAnnotation(FrameAttributes.class))) {
				continue;
			}
			fields2[i] = field;
			i++;
		}
		return fields2;
	}

	public void setAttributesFramsModel(Field[] fieldsOld, FrameBeansModels frameBeansModel) {
		for (Field field : fieldsOld) {
			field.setAccessible(true);
			// 如果是註解了frameAttributes 屬性 就放入map
			if (!WhetherToEmpty.ObjectWhetherToEmpty(field.getAnnotation(FrameAttributes.class))) {
				FrameBeansModels frameBeansModels = new FrameBeansModels();
				// 重新調用這個方法
				FrameAttributes frameAttributes = field.getAnnotation(FrameAttributes.class);
				Field[] fields = frameAttributes.ClassName().getDeclaredFields();
				if (field.getDeclaringClass().getName().equals(frameAttributes.ClassName().getName())) {
					Log4j.Log4JOutError("不能注入一個無限循環的屬性");
					continue;
				}
				getFrameBeansModels(fields, frameBeansModels);

				frameBeansModel.getFrameBeansMap().put(frameAttributes.ClassName().getName(), frameBeansModels);
			}
		}
	}
}
